{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0.0-alpha0\n",
      "sys.version_info(major=3, minor=7, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.0.3\n",
      "numpy 1.16.2\n",
      "pandas 0.24.2\n",
      "sklearn 0.20.3\n",
      "tensorflow 2.0.0-alpha0\n",
      "tensorflow.python.keras.api._v2.keras 2.2.4-tf\n"
     ]
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "import tensorflow as tf\n",
    "\n",
    "from tensorflow import keras\n",
    "\n",
    "print(tf.__version__)\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, tf, keras:\n",
    "    print(module.__name__, module.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".. _california_housing_dataset:\n",
      "\n",
      "California Housing dataset\n",
      "--------------------------\n",
      "\n",
      "**Data Set Characteristics:**\n",
      "\n",
      "    :Number of Instances: 20640\n",
      "\n",
      "    :Number of Attributes: 8 numeric, predictive attributes and the target\n",
      "\n",
      "    :Attribute Information:\n",
      "        - MedInc        median income in block\n",
      "        - HouseAge      median house age in block\n",
      "        - AveRooms      average number of rooms\n",
      "        - AveBedrms     average number of bedrooms\n",
      "        - Population    block population\n",
      "        - AveOccup      average house occupancy\n",
      "        - Latitude      house block latitude\n",
      "        - Longitude     house block longitude\n",
      "\n",
      "    :Missing Attribute Values: None\n",
      "\n",
      "This dataset was obtained from the StatLib repository.\n",
      "http://lib.stat.cmu.edu/datasets/\n",
      "\n",
      "The target variable is the median house value for California districts.\n",
      "\n",
      "This dataset was derived from the 1990 U.S. census, using one row per census\n",
      "block group. A block group is the smallest geographical unit for which the U.S.\n",
      "Census Bureau publishes sample data (a block group typically has a population\n",
      "of 600 to 3,000 people).\n",
      "\n",
      "It can be downloaded/loaded using the\n",
      ":func:`sklearn.datasets.fetch_california_housing` function.\n",
      "\n",
      ".. topic:: References\n",
      "\n",
      "    - Pace, R. Kelley and Ronald Barry, Sparse Spatial Autoregressions,\n",
      "      Statistics and Probability Letters, 33 (1997) 291-297\n",
      "\n",
      "(20640, 8)\n",
      "(20640,)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "\n",
    "housing = fetch_california_housing()\n",
    "print(housing.DESCR)\n",
    "print(housing.data.shape)\n",
    "print(housing.target.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(11610, 8) (11610,)\n",
      "(3870, 8) (3870,)\n",
      "(5160, 8) (5160,)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "x_train_all, x_test, y_train_all, y_test = train_test_split(\n",
    "    housing.data, housing.target, random_state = 7)\n",
    "x_train, x_valid, y_train, y_valid = train_test_split(\n",
    "    x_train_all, y_train_all, random_state = 11)\n",
    "print(x_train.shape, y_train.shape)\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "print(x_test.shape, y_test.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler()\n",
    "x_train_scaled = scaler.fit_transform(x_train)\n",
    "x_valid_scaled = scaler.transform(x_valid)\n",
    "x_test_scaled = scaler.transform(x_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"model\"\n",
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "input_2 (InputLayer)            [(None, 8)]          0                                            \n",
      "__________________________________________________________________________________________________\n",
      "dense_3 (Dense)                 (None, 30)           270         input_2[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "dense_4 (Dense)                 (None, 30)           930         dense_3[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_1 (Concatenate)     (None, 38)           0           input_2[0][0]                    \n",
      "                                                                 dense_4[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "dense_5 (Dense)                 (None, 1)            39          concatenate_1[0][0]              \n",
      "==================================================================================================\n",
      "Total params: 1,239\n",
      "Trainable params: 1,239\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# 函数式API 功能API\n",
    "input = keras.layers.Input(shape=x_train.shape[1:])\n",
    "hidden1 = keras.layers.Dense(30, activation='relu')(input)\n",
    "hidden2 = keras.layers.Dense(30, activation='relu')(hidden1)\n",
    "# 复合函数: f(x) = h(g(x))\n",
    "\n",
    "concat = keras.layers.concatenate([input, hidden2])\n",
    "output = keras.layers.Dense(1)(concat)\n",
    "\n",
    "model = keras.models.Model(inputs = [input],\n",
    "                           outputs = [output])\n",
    "\n",
    "model.summary()\n",
    "model.compile(loss=\"mean_squared_error\", optimizer=\"sgd\")\n",
    "callbacks = [keras.callbacks.EarlyStopping(\n",
    "    patience=5, min_delta=1e-2)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 11610 samples, validate on 3870 samples\n",
      "Epoch 1/100\n",
      "11610/11610 [==============================] - 1s 101us/sample - loss: 1.7293 - val_loss: 0.8529\n",
      "Epoch 2/100\n",
      "11610/11610 [==============================] - 1s 64us/sample - loss: 0.6980 - val_loss: 0.7257\n",
      "Epoch 3/100\n",
      "11610/11610 [==============================] - 1s 63us/sample - loss: 0.6453 - val_loss: 0.6850\n",
      "Epoch 4/100\n",
      "11610/11610 [==============================] - 1s 85us/sample - loss: 0.6151 - val_loss: 0.6576\n",
      "Epoch 5/100\n",
      "11610/11610 [==============================] - 1s 76us/sample - loss: 0.5935 - val_loss: 0.6316\n",
      "Epoch 6/100\n",
      "11610/11610 [==============================] - 1s 67us/sample - loss: 0.5753 - val_loss: 0.6182\n",
      "Epoch 7/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.5621 - val_loss: 0.5981\n",
      "Epoch 8/100\n",
      "11610/11610 [==============================] - 1s 64us/sample - loss: 0.5495 - val_loss: 0.5862\n",
      "Epoch 9/100\n",
      "11610/11610 [==============================] - 1s 62us/sample - loss: 0.5390 - val_loss: 0.5735\n",
      "Epoch 10/100\n",
      "11610/11610 [==============================] - 1s 62us/sample - loss: 0.5309 - val_loss: 0.5687\n",
      "Epoch 11/100\n",
      "11610/11610 [==============================] - 1s 64us/sample - loss: 0.5223 - val_loss: 0.5575\n",
      "Epoch 12/100\n",
      "11610/11610 [==============================] - 1s 63us/sample - loss: 0.5175 - val_loss: 0.5526\n",
      "Epoch 13/100\n",
      "11610/11610 [==============================] - 1s 65us/sample - loss: 0.5096 - val_loss: 0.5431\n",
      "Epoch 14/100\n",
      "11610/11610 [==============================] - 1s 63us/sample - loss: 0.5038 - val_loss: 0.5351\n",
      "Epoch 15/100\n",
      "11610/11610 [==============================] - 1s 68us/sample - loss: 0.4983 - val_loss: 0.5287\n",
      "Epoch 16/100\n",
      "11610/11610 [==============================] - 1s 63us/sample - loss: 0.4940 - val_loss: 0.5236\n",
      "Epoch 17/100\n",
      "11610/11610 [==============================] - 1s 63us/sample - loss: 0.4893 - val_loss: 0.5187\n",
      "Epoch 18/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4849 - val_loss: 0.5140\n",
      "Epoch 19/100\n",
      "11610/11610 [==============================] - 1s 65us/sample - loss: 0.4815 - val_loss: 0.5111\n",
      "Epoch 20/100\n",
      "11610/11610 [==============================] - 1s 63us/sample - loss: 0.4773 - val_loss: 0.5070\n",
      "Epoch 21/100\n",
      "11610/11610 [==============================] - 1s 74us/sample - loss: 0.4734 - val_loss: 0.5102\n",
      "Epoch 22/100\n",
      "11610/11610 [==============================] - 1s 63us/sample - loss: 0.4704 - val_loss: 0.5025\n",
      "Epoch 23/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4669 - val_loss: 0.4957\n",
      "Epoch 24/100\n",
      "11610/11610 [==============================] - 1s 63us/sample - loss: 0.4637 - val_loss: 0.4966\n",
      "Epoch 25/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4607 - val_loss: 0.4891\n",
      "Epoch 26/100\n",
      "11610/11610 [==============================] - 1s 65us/sample - loss: 0.4579 - val_loss: 0.4860\n",
      "Epoch 27/100\n",
      "11610/11610 [==============================] - 1s 62us/sample - loss: 0.4553 - val_loss: 0.4826\n",
      "Epoch 28/100\n",
      "11610/11610 [==============================] - 1s 63us/sample - loss: 0.4520 - val_loss: 0.4829\n",
      "Epoch 29/100\n",
      "11610/11610 [==============================] - 1s 65us/sample - loss: 0.4494 - val_loss: 0.4774\n",
      "Epoch 30/100\n",
      "11610/11610 [==============================] - 1s 65us/sample - loss: 0.4466 - val_loss: 0.4795\n",
      "Epoch 31/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4438 - val_loss: 0.4702\n",
      "Epoch 32/100\n",
      "11610/11610 [==============================] - 1s 68us/sample - loss: 0.4414 - val_loss: 0.4668\n",
      "Epoch 33/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4386 - val_loss: 0.4639\n",
      "Epoch 34/100\n",
      "11610/11610 [==============================] - 1s 70us/sample - loss: 0.4372 - val_loss: 0.4627\n",
      "Epoch 35/100\n",
      "11610/11610 [==============================] - 1s 68us/sample - loss: 0.4345 - val_loss: 0.4601\n",
      "Epoch 36/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4318 - val_loss: 0.4618\n",
      "Epoch 37/100\n",
      "11610/11610 [==============================] - 1s 65us/sample - loss: 0.4296 - val_loss: 0.4558\n",
      "Epoch 38/100\n",
      "11610/11610 [==============================] - 1s 71us/sample - loss: 0.4271 - val_loss: 0.4534\n",
      "Epoch 39/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4262 - val_loss: 0.4511\n",
      "Epoch 40/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4237 - val_loss: 0.4481\n",
      "Epoch 41/100\n",
      "11610/11610 [==============================] - 1s 71us/sample - loss: 0.4214 - val_loss: 0.4470\n",
      "Epoch 42/100\n",
      "11610/11610 [==============================] - 1s 65us/sample - loss: 0.4187 - val_loss: 0.4453\n",
      "Epoch 43/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4172 - val_loss: 0.4416\n",
      "Epoch 44/100\n",
      "11610/11610 [==============================] - 1s 69us/sample - loss: 0.4160 - val_loss: 0.4411\n",
      "Epoch 45/100\n",
      "11610/11610 [==============================] - 1s 70us/sample - loss: 0.4133 - val_loss: 0.4348\n",
      "Epoch 46/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4115 - val_loss: 0.4336\n",
      "Epoch 47/100\n",
      "11610/11610 [==============================] - 1s 72us/sample - loss: 0.4097 - val_loss: 0.4324\n",
      "Epoch 48/100\n",
      "11610/11610 [==============================] - 1s 72us/sample - loss: 0.4079 - val_loss: 0.4288\n",
      "Epoch 49/100\n",
      "11610/11610 [==============================] - 1s 66us/sample - loss: 0.4070 - val_loss: 0.4271\n",
      "Epoch 50/100\n",
      "11610/11610 [==============================] - 1s 67us/sample - loss: 0.4049 - val_loss: 0.4294\n"
     ]
    }
   ],
   "source": [
    "history = model.fit(x_train_scaled, y_train,\n",
    "                    validation_data = (x_valid_scaled, y_valid),\n",
    "                    epochs = 100,\n",
    "                    callbacks = callbacks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAecAAAEzCAYAAAALosttAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzt3XmYHVWB9/HvuXvvW7o7S3eSzk5IQlhCEpDQwy4ouLEJCijw6ijqOMMYlweXmdFRXvVVBwUGUXQQzAAKShQQ02wGDISELJCdJJ2ks/S+317O+8e5vaaTvunc3K5O/z7PU0/VrTpd93Q9kF+fU6dOGWstIiIi4h2+4a6AiIiI9KVwFhER8RiFs4iIiMconEVERDxG4SwiIuIxCmcRERGPGTScjTEPGmMOGGPWH+G4Mcb82Biz1RjzljHmjMRXU0REZPSIp+X8S+Cyoxx/LzA9ttwO/Oz4qyUiIjJ6DRrO1toXgaqjFLkK+JV1XgWyjTHjElVBERGR0SYR95wnALt7fS6P7RMREZEhCCTzy4wxt+O6volEImdOnDixz/HWDtjX2ElhqiElYJJZtZNaZ2cnPp/G/iWDrnXy6Fonj651YmzevPmQtTY/nrKJCOc9QHGvz0WxfYex1t4P3A8wc+ZMu2nTpj7HN+yt5Yofv8y9N57JZXPGJqBqAlBWVkZpaelwV2NU0LVOHl3r5NG1TgxjzM54yybiT6GngI/HRm0vAmqttfuGcqJwwA9Aa3tHAqolIiIyMg3acjbGPAKUAmOMMeXA14EggLX2XmA5cDmwFWgCbhlqZcIB97dCa1vnUE8hIiIy4g0aztba6wc5boHPJKIykaBaziIiIkkdEDaYcDDWcm5Xy1lExGva2tooLy+npaVluKviaZFIhKKiIoLB4JDP4a1wjnVrt7Sp5Swi4jXl5eVkZGQwefJkjNETNQOx1lJZWUl5eTklJSVDPo+nxsaH/D6MUctZRMSLWlpayMvLUzAfhTGGvLy84+5d8FQ4G2MIB3wKZxERj1IwDy4R18hT4QzucSp1a4uIyEDS09OHuwpJ4blwjgR9epRKRERGNc+Fczjg16NUIiJyVNZa7rzzTubMmcPcuXP57W9/C8C+fftYsmQJ8+fPZ86cObz00kt0dHRw8803d5f94Q9/OMy1H5ynRmuDG7HdopaziIgcxRNPPMGaNWtYu3Ythw4dYsGCBSxZsoTf/OY3XHrppXz1q1+lo6ODpqYm1qxZw549e1i/fj0ANTU1w1z7wXkunCNBtZxFRLzum3/YwMa9dQk95+zxmXz9/afGVfbll1/m+uuvx+/3U1hYyPnnn8+qVatYsGABn/jEJ2hra+MDH/gA8+fPZ8qUKWzfvp077riDK664gksuuSSh9T4RPNitrdHaIiIyNEuWLOHFF19kwoQJ3HzzzfzqV78iJyeHtWvXUlpayr333sutt9463NUclOdazuGgj+aoWs4iIl4Wbwv3RDnvvPO47777uOmmm6iqquLFF1/k7rvvZufOnRQVFXHbbbfR2trK6tWrufzyywmFQnz4wx9m5syZ3HjjjcNa93h4LpwjAT81TW3DXQ0REfGwD37wg6xcuZLTTjsNYwzf+973GDt2LA899BB33303wWCQ9PR0fvWrX7Fnzx5uueUWOjtdr+x3vvOdYa794DwXzuGgurVFRGRgDQ0NgJvo4+677+buu+/uc/ymm27ipptuOuznVq9enZT6JYoH7zlrEhIRERndPBfOEbWcRURklPNcOIcDflrVchYRkVHMg+Hso0UtZxERGcW8F85BP9H2Tqy1w10VERGRYeG9cA64Kum+s4iIjFYKZxEREY/xXDhHgn4ADQoTEZHjdrT3P7/77rvMmTMnibWJn+fCWS1nEREZ7bwXzl0tZ72ZSkRE+lm6dCn33HNP9+dvfOMb/Pu//zsXXnghZ5xxBnPnzuXJJ5885vO2tLRwyy23MHfuXE4//XRWrFgBwIYNGzj77LOZP38+8+bNY8uWLTQ2NnLFFVdw2mmnMWfOnO53SSeS56bvjMRaznqns4iIh/1pKVSsS+w5x86F9/7nUYtce+21fOELX+Azn/kMAMuWLeOZZ57hc5/7HJmZmRw6dIhFixZx5ZVXYoyJ+6vvuecejDGsW7eOd955h0suuYTNmzdz77338vnPf54bbriBaDRKR0cHy5cvZ/z48Tz99NMA1NbWDv13PgK1nEVEZMQ4/fTTOXDgAHv37mXt2rXk5OQwduxYvvKVrzBv3jwuuugi9uzZw/79+4/pvC+//HL326pmzZrFpEmT2Lx5M4sXL+bb3/423/3ud9m5cycpKSnMnTuX5557ji996Uu89NJLZGVlJfz39FzLufues1rOIiLeNUgL90S6+uqreeyxx6ioqODaa6/l4Ycf5uDBg7zxxhsEg0EmT55MS0tLQr7rox/9KAsXLuTpp5/m8ssv57777uOCCy5g9erVLF++nK997WtceOGF3HXXXQn5vi6eC+eu0dotajmLiMgArr32Wm677TYOHTrECy+8wLJlyygoKCAYDLJixQp27tx5zOc877zzePjhh7ngggvYvHkzu3btYubMmWzfvp0pU6bwuc99jl27dvHWW28xa9YscnNzufHGG8nOzuaBBx5I+O/ouXBWy1lERI7m1FNPpb6+ngkTJjBu3DhuuOEG3v/+9zN37lzOOussZs2adczn/Md//Ec+/elPM3fuXAKBAL/85S8Jh8MsW7aMX//61wSDwe7u81WrVnHnnXfi8/kIBoP87Gc/S/jv6N1w1qNUIiJyBOvW9QxGGzNmDCtXrhywXNf7nwcyefJk1q9fD0AkEuEXv/jFYWWWLl3K0qVL++y79NJLufTSS4dS7bh5bkBYd7e2JiEREZFRSi1nERE5qa1bt46PfexjffaFw2Fee+21YarR4LwXznqUSkREEmju3LmsWbNmuKtxTLzXra1JSEREPEuv8x1cIq6R58I54Pfh9xm1nEVEPCYSiVBZWamAPgprLZWVlUQikeM6z7B1a0dajjx7Szjg06NUIiIeU1RURHl5OQcPHhzuqnhaJBKhqKjouM4xbOEcbG+E9lYIhA87Fgn6NQmJiIjHBINBSkpKhrsao8LwdWvbTihfNeAhtZxFRGQ0G8Z7zga2lw14JBzw6VEqEREZtYYtnDv8Ydj+woDHIkG/JiEREZFRaxjDORX2vAEtdYcdU8tZRERGs2EL5/ZACtgO2PnKYcfCAb8epRIRkVFrGFvOEQikDHjfORz0aRISEREZtYZ3QNikxQPed3YtZ4WziIiMTsM7Q1jJ+XDwbaiv6LM7HPSpW1tEREat4Q3nKaVuvePFPrsjAb+ecxYRkVFreMN57DxIyTnsvrNaziIiMprFFc7GmMuMMZuMMVuNMUsHOD7RGLPCGPOmMeYtY8zl8X27D0qWuPvOvSZS1wxhIiIymg0azsYYP3AP8F5gNnC9MWZ2v2JfA5ZZa08HrgN+GncNSs6HunKo3Na9KxLUgDARERm94mk5nw1stdZut9ZGgUeBq/qVsUBmbDsL2Bt3DaaUuvWOsu5d4YCPaEcnHZ16LZmIiIw+8byVagKwu9fncmBhvzLfAJ41xtwBpAEXDXQiY8ztwO0A+fn5lJWVgbUsCudT/9pjbGicBsCeXVEA/rKijLDfxP3LyMAaGhrctZYTTtc6eXStk0fXOvkS9crI64FfWmu/b4xZDPzaGDPHWtunb9paez9wP8DMmTNtaWmpO1B3KZG3/0jpkvPA52dHcAds3sjCxeeSnRpKUBVHr7KyMrqvtZxQutbJo2udPLrWyRdPt/YeoLjX56LYvt4+CSwDsNauBCLAmLhrUVIKLTWwby3gJiEBNEuYiIiMSvGE8ypgujGmxBgTwg34eqpfmV3AhQDGmFNw4Xww7lpMOd+td7jZwsIBVy09TiUiIqPRoOFsrW0HPgs8A7yNG5W9wRjzLWPMlbFi/wzcZoxZCzwC3GytjX80V3oBFMzuft45EnQtZ43YFhGR0Siue87W2uXA8n777uq1vRE497hqMqUUXn8Q2lq6W856p7OIiIxGwztDWG8l50N7C+x+jXCwq1tbLWcRERl9vBPOk88F44cdL/R0a2tAmIiIjELeCedwBhSdBdvL1K0tIiKjmnfCGdx9571vktLRAKhbW0RERidvhXPJ+WA7ydr/KqBHqUREZHTyVjgXLYBgKml7XwE0CYmIiIxO3grnQAgmnUNk98uAWs4iIjI6eSucAaaU4q/cTCFVuucsIiKjkvfCucRN5XmOb4NGa4uIyKjkvXAunAOpeZwXWK+Ws4iIjEreC2efD0qWcK7ZQGtULWcRERl9vBfOAFNKKTRVZDTuGO6aiIiIJJ03wzl233lS7aphroiIiEjyeTOcc0vYawqZWv/6cNdEREQk6bwZzsCbwdOZ1bQK9m8c7qqIiIgklWfD+fH0j9Jk0uCR66CxcrirIyIikjSeDeemSAF359wF9RXwvzdBR9twV0lERCQpPBvO4YCfDb4ZcOVP4N2X4E9fGu4qiYiIJEVguCtwJOGAj9a2DjjtWjiwAV75ERTOhgW3DnfVRERETijPtpwjQX/PDGEXfh2mX+pazzteHN6KiYiInGCeDefuljOAzw8ffgByp8Kyj0OVJicREZGTl3fDOeijqa0Da63bEcmE6x8Ba+GR66G1fngrKCIicoJ4Npxnj8uipqmNP761r2dn3lS45iE4tBmeuB069WIMERE5+Xg2nK9dUMy8oiy++YcN1DRFew5MKYXLvgOblsNf/224qiciInLCeDac/T7Ddz40l+qmNr69/O2+B8++Hc64CV7+Aax7bHgqKCIicoJ4NpwBTh2fxa3nlbDs9XL+tu1QzwFj4PL/CxPPgd9/GtY8MnyVFBERSTBPhzPAFy6cwcTcVL76u/W0tPV6v3MgBNc9DMUL4fefgme+Ch3tw1dRERGRBPF8OKeE/Hz7g3PZcaiRn/x1S9+Dqbnwsd+5bu6V/wW/uRqaq4enoiIiIgni+XAGeM/0MXzojAnc98J23qmo63vQH4TL74b3/xh2vAT/fQEc3DQ8FRUREUmAERHOAF+7YjaZKUGWPr6Ojk57eIEzb4Kb/+ief/7vC2HTn5NfSRERkQQYMeGcmxbirvfNZs3uGn698t2BC01cBLeXQd4U96rJl77vJi0REREZQUZMOANcNX88S2bkc/czm9hb0zxwoawiuOXPMOfD8Py34PFPQrQpuRUVERE5DiMqnI0x/McH5tBhLXc9ub5nas/+QqluLu6LvgHrn4AHL4XqncmsqoiIyJCNqHAGKM5N5YsXz+Avbx9g+bqKIxc0Bt7zT/DR37pgvv982PKX5FVURERkiEZcOAN84twS5kzI5OtPbaC2qe3ohWdcCrevgMwJ8PBHoOw/NSe3iIh42ogM54Dfx39+aB5Vja18509vD/4DeVPhk8/BaddB2XfgN9dAU9WJr6iIiMgQjMhwBpgzIYtbz5vCo6t284NnNx35/nOXUCp84GdwxQ9gxwtw3/mw983kVFZEROQYjNhwBvjXS2dyzVlF/PivW/nyE+to7xiku9oYWPBJN5rbdsLPL4U3HkpOZUVEROI0osM54Pfx3Q/P444LpvHoqt186n/eoDnaMfgPFp0J/+dFmHQO/OFz8ORnoO0Ij2aJiIgk2YgOZ3CPV/3zJTP51lWn8vw7B7jhgVepbowO/oNpeXDj47DkTnjzf+Dnl8DmZ6EzjnAXERE5gUZ8OHf5+OLJ3PPRM1i/p46r71vJniNNUtKbzw8XfA2u/y3UV7gXZ/zoNHjhe1C398RXWkREZAAnTTgDXD53HL/65Nnsr23hQz995fCXZBzJzMvgnzbA1Q+5kd0r/gN+OAce+aha0yIiknQnVTgDLJqSx7JPLQbg6ntX8tr2yvh+MBCCUz8AH38SPvcmnHMHlP+9X2t63wmsuYiIiHPShTPAKeMyefzT55CfEeZjD/6dP68/xlDNnQIXfxP+aSNc/cterelT4el/0TujRUTkhDopwxmgKCeVxz91DqeOz+TTD6/mG09toLG1/dhOEgjBqR90rek7VsNZt8DrP4efnOUGkWmmMREROQHiCmdjzGXGmE3GmK3GmKVHKHONMWajMWaDMeY3ia3m0OSkhfjNrYv4+KJJPLTyXS754YuUbTowtJPlTYUrvg+3v+C2n/yMe6HGvrUJrbOIiMig4WyM8QP3AO8FZgPXG2Nm9yszHfgycK619lTgCyegrkOSEvLzzavm8NinFhMJ+rj5F6v44m/XxPe41UDGzXOTmFz1U6jaDveXqqtbREQSKp6W89nAVmvtdmttFHgUuKpfmduAe6y11QDW2iE2T0+cMyflsvzz5/G5C6bx1Nq9XPSDF/jD2r2DT/s5EJ8PTr8B7ngDFtyqrm4REUmoeMJ5ArC71+fy2L7eZgAzjDGvGGNeNcZclqgKJlI44OeLl8zkD3e8h6KcFO545E1u+9Xr7Ksd4uxgKdlw+d2Hd3VvfhY6BnlbloiIyBGYwVqOxpiPAJdZa2+Nff4YsNBa+9leZf4ItAHXAEXAi8Bca21Nv3PdDtwOkJ+ff+ayZcsS+Kscm05refbddp7YEsXvg6tnhCgtDuAzZmgntJ0U7i9j6raHCLXVEA1mcTD/XPYXnk9d5kw3r/cwaWhoID09fdi+fzTRtU4eXevk0bVOjH/4h394w1p7Vjxl4wnnxcA3rLWXxj5/GcBa+51eZe4FXrPW/iL2+XlgqbV21ZHOO3PmTLtp06Z46nhC7apsYukTb/G3bZWcMi6Tpe+dxZLpYzBDDdP2KGx9Dt5aBpv/DO0tkDMZ5l4Nc6+B/BkJrX88ysrKKC0tTfr3jka61smja508utaJYYyJO5zj6dZeBUw3xpQYY0LAdcBT/cr8HiiNffkYXDf39rhrPIwm5qXy8K0L+fH1p9PQ2sZND/6dGx54jXXltUM7YSAEs66Aax6Cf9niBo7lTIaXvg/3LID7lsDf/gvq9yf09xARkZPHoOFsrW0HPgs8A7wNLLPWbjDGfMsYc2Ws2DNApTFmI7ACuNNaG+fUXMPPGMOVp43n+S+W8vX3z+adinre/18vc8cjb7KrsmnoJ45kuoFjH38Svvg2XPptwMCzX4UfnAIPXwMbn3StbRERkZhAPIWstcuB5f323dVr2wJfjC0jVijg45ZzS/jImUXc/+J2HnhpB39ev48bFk7ijgumkZceHvrJM8bC4s+45eBmWPsbWPsoLHsGUnJh3jUw/wb3qJaIiIxqJ+0MYccjIxLkny+ZyQt3lvKRM4v59as7Of/uMn7y/BZqmxMwCjt/Blz0DfjCerjhMShZAq8/CPedB/e+B169FxpHTMeDiIgkWFwt59GqIDPCdz40l0++p4Tv/fkdvv/cZv5rxVaumDuO686eyILJOUMfOAbgD8D0i93SVAXrHoM1/wN//hI8+zUoWgB5U9xc372XcEbifkkREfEchXMcphWkc//Hz2L9nloeXbWLJ9/cyxNv7mFKfhrXLSjmQ2cUMeZ4urwBUnNh4e1uqVgPax+BPathy1+goaJv2bSCnqAePx9OeT9kjj++7xcREc9QOB+DOROy+PcJc/nK5afw9Fv7+O2q3Xx7+Tvc/cwmLp5dyLULJnLetDH4fMf5TPPYOTD2P3o+tzZA9Q43XWj3sgO2l7l713/6Ekxc7F7SMftKd39bRERGLIXzEKSGAlx9VjFXn1XMlv31/HbVbh5fXc7ydRVMyE7hI2cW8ZEziyjOTU3MF4bTYexct/R3aAts+D1s+B386U7407/CpHPdu6lnXwXpBYmpg4iIJI3C+ThNL8zga++bzZ2XzeS5jft59O+7+fFft/Cj57ewsCSXj5xZxOVzx5EWPkGXesx0OP9OtxzcFAvqJ2D5v3QHdZF/OmyOuilGsyeCP3hi6iIiIgmhcE6QcMDP++aN533zxrO3ppnfvbmHx94o587H3uLrT23gvXPG8ZEzi1hYknv83d5Hkj8TSr/klgNvu9b0+ieYVvkSbHvQlTF+yJkEuVNdWOdOdYPO8k+BrP5TpouIyHBQOJ8A47NT+Mw/TOMfS6eyelc1j71Rzh/W7uPx1eUU5aTw4TOKuHL+eKbmn8C5agtOcUvpl3nluSc5d9ZYqNwGVdt61jv/Bm2NPT8zZgZMuximX+S6xgPHOchNRESGROF8AhljOHNSLmdOyuWu953KsxsreOyN8u5u72kF6Vwyu5BLTh3LvAlZJ6ZFbQxtoWyYuMgtvVkLDftdWO9bA1v/AqsegFfvgWCqe/56+sUusHMmJb5uIiIyIIVzkqSE/Fw1fwJXzZ/Avtpmnt2wn2c3VnDfi9v5adk2CjPDXDy7kEtPHcvCkjxCgSTMD2OMG9mdMRYmn+tmL4s2wrsvw5bn3As8Nv/ZlR0zA6bFWtQTF0Na3omvn4jIKKVwHgbjslK46ZzJ3HTOZGqaoqzYdIBn1u/n8Tf28D+v7iIjEuCCWQWUzsxnYUke47NTkle5UBrMuNQt1rpW9dbnXFi//iC8+lNXbsxMmLQYJp7j1tkTk1dHEZGTnMJ5mGWnhvjg6UV88PQiWto6eHnLIZ7dWMFf3j7Ak2v2AlCcm8LZk/NYWJLLwim5TMxNPb6ZyeJlDIyZ5pZFn4b2Vtj7prtXvWslrH8C3vilK5tZFAvrxW5ilILZEEziHxUiIicRhbOHRIJ+LppdyEWzC+notLxTUcdr26v4+44qVmw6wOOrywEozAxzdokL60VTcpman56csA6E+9677uyA/RtcUO/8G+x4Edb9rztmfK4rfOy8nme0x85Td7iISBwUzh7l9xlOHZ/FqeOz+MR7SrDWsvVAA6/ucGH92vZK/rDWtazzM8IsmpLH4il5LJ6ax+S8JLWsfX73Fq1x82Dh/3Hd4NXvQsW62PIW7HwF1i3r+ZnMCVA4xz32lTfNPaedNx3SxriWuoiIKJxHCmMM0wszmF6YwccWTcJay87KJl7dXsnK7ZWs3NYT1uOyIiyekseiqXmcMzWJLVVjILfELbOv7NnfWAn718G+t1xo718P21dAR6/3WEeyXEiPmd4rtKe5+cPVPS4io4zCeYQyxjB5TBqTx6Rx3dkTsday7WAjK7dX8uq2Sso2H+SJN/cAkBM2zNr8KpPHpFEyJpWSMemUjEmlODeVcMB/4iublgdTSt3SpbMDanZB5VY3BWnlFrfeXuZe+tFbZpGbMCVvaiywY+ucSZrtTEROSgrnk4QxhmkF6UwrSOdjiybR2WnZfKCeldsq+csbm2lu7+DP6/dR3dTzPmqfcROmlIxJY1pBOmdOymHB5FwKMyMnvsI+f08re/rFfY+1NrjQrtzqXvJRudWNGl//OLTU9vql/W6UeP9XauZOccGtSVREZIRSOJ+kfD7DrLGZzBqbSUnbTkpLzwWgtqmNHZWN7DjUwI5DTbx7qJEdhxp59O+7+cUr7wIwMTeVsya7oF4wOZep+WnJuYfdJZzuRnyPn993v7XuvddV23oCu+stXeWroLWuV2EDWcUu/LOK3T3t9AL3us3e26m57g8FEREPUTiPMlmpQeanZjO/OLvP/raOTjburWPVu1WsereKFzYd5InVrls8Ny3EmZNyOGtSDrPGZTKzMIPCzHByAxvcPe20PLcUn933WHdwb++3bINtf4XGg9DZNsA5fZCaB+ljIbvYtcSzit12Vuxzal7fwWrWQnM11Fe4GdYaDrh3bjccYNquHZBTAcULIWeyBrmJyJAonAWAoN/HacXZnFacza3nTcFay45Djbz+bnV3YD+3cX93+YxIgJmFGcwYm8GMgnRmjM1gZmEGeenD1JXcJ7gXHH7cWmipgYaD0HjAhXXDQbduPAB1+9xI8x0vQbS+788GUyGryE3Q0nDQBfJAQR9MZWxnJ/zuafc5rQAmLnRBXbzIjWpXV7uIxEHhLAMyxjAlP50p+elcs6AYgOrGKJv317N5fz2b9tezuaKBp9/ax2+ae4IqLy3E9MJ0ZsRGlk8vcNu5aaHh+lUcYyAlxy35M45crivEa3ZD7e5e611uatP8UyCjENJ7LRljXTd5KJ2Xy/5K6eyxsOtV2P132P0qvP0Hd25/GCac4Vr9489w21nFal2LyGEUzhK3nLQQC6fksXBKz+NZ1loO1reyaX89myrqY+HdwBOr99DQ2t5dbkx6iGmxoJ5ekM7EvDSKc1KYkJOSnBHj8eod4uPmDeHn/VB4qlsWfNLtq6+IBfVrbln5056Wd2oejD/dhfX4092SOS5xv4+IjEgKZzkuxhgKMiMUZEY4b3p+935rLftqW9hyoIEtsdb2lgOHhza4Gc+Kc9yjXUU5KRTnuPWkMWmMy4ycuPdfJ0vGWPfcd9ez3+2tbma1vavddKh73oRt/xdsZ6z8OBfuxufKdkShvQXao9DR6va1t4LtgPxZriVedLZbp40Zvt9TRBJG4SwnhDGG8dkpjM9O4fwZfUO7oq6F3VXN7K5qory6md3VTZRXN/H3HVU8uaaZTttznlDAx8TcVCbnpTIpL63XOo3x2REC/iS8vSvRArHu7Qln9OyLNrkJWroC+8BGF86BCPhDroXdtR0I99y7rlgHf/sJdMb+4Mmd4u5xFy1w64JTNBpdZARSOEtSGWMYl5XCuKwUzi7JPex4W0cnFbUt7K5qYmdVE+9WNrLzkFu/srWS5raO7rIBn2FCTgoTc12re2JuKsU5bj0xN5Ws1BE0QUko1Q0em7jw2H+2rRn2rnFd5uWr3Hu5uyZyCaVD9iRIz3f3x9Ni6/SCnsfJ0gtd+PtG4B86IicphbN4StDvozgWtuf0O2at5UB9K+8eamRnZRM7KhvZXdXE7qom/rSu7wQrAJmRAMW5qYzPTqEwM0xhRoSCzDAFmZHu7dzU0MjvNg+muDeCTVrsPlsL1Ttg9yrY8zrU7nEj0netdI99tbccfg5foGdwW8a4nvd8d2+Pc6PWbWfP0tkR2+7o2RfOco+Q+fVPi8jx0P9BMmIYYyjMjFCYGekzKK1LfUsbu6ua2VXlusl3Vblld1UTr79bdVh4g2t9F2SEGZsVoSh2r7tn7brlI8ER1i1sTM9Maadd2/cwUAWBAAAUqUlEQVSYtdBa70K68UDPc9r1FbFln5vc5d2X3aj1ofCH3Dzp+TNdt3r+THdvPHfKwNOtWuta/y21biKZllrXpT/uNE3PKqOWwllOGhmRILPHB5k9PnPA463tHRysb2V/XSsH6lrYX9fC/vpW9te1UFHbwprdNSxft4/23je9cW/96grt8dkRJmS7bvmu7ayUYPInZBkqYyCS6ZYx045etq3ZhXd9BdTtdYPQjM8tvtja+GOfY+umSjj4Dhx4B/a8ARue6DmfL+jmRE/Pd38gtNTGlrqBnxsPZ0LJEph6AUy70LXIRUYJhbOMGuGAP9YqTj1imY5Oy/66FsqrmymvbmJPdbPbrmnirfIanlnfQrSjs8/PpIb83YPfaGplVes7jEkPMyY9TF56iPzYdlZKcGR1oQdTXCAeTyhGG90LTQ5ugoNvu3VTpbv3nTvVvY0skhX7gyG2Hc5yE8FsW+Fmd3vnj+5cuVN7gnryeYn4DUU8S+Es0ovf1zPKfKABa52dlsrGKHtrmtlb08yemmb21rS4z7XN7DzYwSt7t9PRr/UNrgs9Ny1EfkY41j3v1mNjXfVd+3LTQiOnJT6YUNrA86TH49QPui7vQ1tcSG97HtY8DKv+G3xBTk+fBpVz3aQwXffG08f23C8PpSX+9xFJEoWzyDHw+Qz5GWHyM8Kc1m9+coCysjKWLDmfmuY2DjW0xpYoh+rddmVDlIMNriv9rfIaDjVEDztHyO8jPyPsBq9lhCnIiLh1ptvuOpaXFsY/klriQ2GMm9EtfwYs+pTrWt+1ErY+D+ufcyPU6yvc89/9hTN7Rqan5cdGqsdefJLWtW+MW4fSNVpdPEXhLJJgvlgLOTctxIzCjKOWjbZ3crChlYraFg7UtVBR18L+OhfeB+pb2H6wkVe3V1HbfPg9WZ+B3LQwY9Jda9x1pYe6u9THZPR8zk0LERyJz4T3Fwh3vxv8zdCFlJaW9ky52jWgrX6/WzfE1o2H3KQvjQePPsjNH4JACgQj7pnyYErfdUq2e+Ssz5Lbs52S60asRxvca0+j9e7eemtDbF/sc2qum2Qm/xT3CJ3IABTOIsMoFPAxITuFCdkpRy3XNZjtQH0rB+paOVjfwoFYa/xgfZRDDa1sP9jIoYZWWts7BzxHZiRAXnqYvNgfDnnpIfLSwt3bOaluf05aiNzUECmhETJKvfeUqwWnHL1sexSaDsVGqx/qeQlKW7Nb2lsGXkcboLbc3S9vrgYOv21x7PX2ufvohafC2DlQOMdta751QeEsMiLEM5gN3LPgDa3triu9odV1pzdGqWqIUtXYs72zsonVu6qpaowywO1xACJBH7mpsbBOC5GXFnJTtca69fMzwrHtCJmRwMi4Tx4IQeZ4twxVZwc017igbqqE5qqebeNzXeThDLeE0t37yUNdn9PcHwT7N0DFeti/HvatgY2/7zl/OAtyJ7uWeGpuzx8eKb23ey/ZeuTsJKRwFjmJGGPIiATJiAQpGTP4gKjOTkttcxtVTVGqG6NUNUapbopS1dgWW7v9lY1R3q1s5EDdwC3zcMDX3bXe1aWfm9bVGg+Sk9q3dZ4ZGWEj13vz+XteTzoU4XT3zPcp7+/Z11oP+ze6sN6/3rXSm6vd29Caq113vB24RwRwfwREsnvCOpLltlNzY/fWC9wjbGmxmeFS8zStq8cpnEVGMZ/PkBPryiZ/8PLWWupa2mNd7C1uXdfKwQb37HhlY5T9dS28s6+OysboEbvY/T7jArsryNNDvbrbXdd7Xq+u9xH3GNqxCmccffrWzk5orXVB3VwNTdU9od1c7VryvT9XbnPbTZXuxSn9GZ8L6LQC90dGIKVnzvZA2N1jD0Tctj9M8a49sGqrG2TX1RsQzoj1CMS2g6nqjk8ghbOIxM0YQ1ZKkKyUINMK0o9a1lpLc1tHrPXd0zqvbHRd7JUNXdtRNu6to7KhlbqW9gHP1RXmY9J7Ary5upU17ZvJTgmSnRoiKzXYvZ2dEiQzJXjyjGb3+Xq6sY+FtW6il8aDvWaFOxhbx+63N1W6Mu293njW3hJ7I1ordLYzFWD7IN9l/G50fNYEyIwtWRNitxGK3HZ6oVrscVI4i8gJYYwhNRQgNRSgKM5MaevopLoxyqEGF9qVsRDv2u7av668hv217fxl15ajfD9kRoLd98u7Br65Lvdwd9DnpIZIDwdIDftJDQVICfpPnlA3xnVzp2TDmOlDO0dHOy+teJbzFp5xhFHodW67tc6NmK8td/fUtzwLbU396uMDf9gFtM/vAn2gdXYxjJ3nlnHz3HSwo2y+9tH124qIpwX9vu73gw+mrKyM95y3hLqWdmqaotQ0t1Hb1EZNs2up1zS3URO7b17ZPQiuhuqm6ICTxPQWDvhIDcXCOuQnLeQnMyUYC/kwuWnB2DrUZ8k+Gbvf/QE6AqmxyV2O4ee6HnGr3eOmf60rj00D2+IG1XV2uJemdK9jL1HpaIOq7bDqgZ6XtAQiUDAbxs51YT32NNcS7/2o20nWpa5wFpERK+D3dQdjvDo7LXUtbVTGQruqMUpTtJ3GaAfN0Xaaoh00RztoinbQGG2nOdpBY7SD2qYoOw41Ut0YpTHaMeC5fQZy+o1w7x/gOakhsmLd7lkpQTIjgZH5XvLB9H7EbeycY//5jnao3AL73oKK2LLxSVj90MDlu+6TB1Njz6qn9KwD4V7PrffbF86Mdb1PgMxxbra5rvelDyOFs4iMKj6fcfelU0NMjWMQ3EBa2jqobnLhXt2rdV7dFLuP3hClqinKlgMN3SPg7VEa6+nhAFkpQTIibp2d6ka4Z6eGyOnedl30XfsyIkGCfjMyHmEbCn/APbdecErP29Wsdd3mFW8N/Hx6WzO0N0NbS99n1ZurXZd772Ndxwd6Zj0tv1dgj3f3yg97NC6972Nz/lDsRS5HGKTXfGxveVM4i4gco0jQz7gs93ayeHR0PbLW2EpNUxu1zX2Xuub2Xttt7DjUyOqmGmqaorR1HL0LPhTwEfb7CAZ8hPw+QoHY4veREvKTnRIkqyvgU4Jkp7lwz05xgZ8T645PDfm9H/TGuPvR2cWJOZ+17l553T6o6+p+3+u26/e5R9l2rYxNPHM89fa5R92OgcJZROQE8/ea0vVYWGtpjHZQHWt9Vze5++jVjVHqW9pp6+iktaOTaHsnbbG127a0tnfS3NZORV0L71TUU9N05O54gKDfkBUL7OxY671r5HvV/ih7Unb2mZQmJ9aCH9Fd8sb0vA2tYNaRy3W0uUFw3VOz9hoI17Wvo9V1kXc9a56S0/PseTjDfdfS+P/4UTiLiHiUMYb0cID0cIDi3OOfh7u1vYPa5jZqmtpige/Cvra5awBdG7XNUWqa2thT08LGvXXUNLfRFO3giS3rBzxn17Sw2alBN+o9NpDOrXtthwOkBt2+SLBrca37SMDfvY6EXKvfU614fzA2j/rhb6o7URTOIiKjRDjgpyDDT0HG4KPhe3vuryuYd9bi7hnjemaUa+u+z17dGKWh1U1Q0xhtp6nVDaprbjtya/3I9fS5wXTpsdHxqW50fF5630F1GZEAabE/XtLDASJBj4X6cYgrnI0xlwE/AvzAA9ba/zxCuQ8DjwELrLWvJ6yWIiIybII+0/3O8WPV2ekmo+kK7Oa2Dlra3Lq1rbPP5+ao265tbusO/KrGKNsPNhx1lHwXv8+QFvK7sO4X3Olh97l/oHeVTY8dy4i4HoBQYHi76wcNZ2OMH7gHuBgoB1YZY56y1m7sVy4D+Dzw2omoqIiIjDw+nyEtFozH9Jz0AHqPkq9raaOhpZ3GaDsNLe00tHbQ0NpGY2sH9S3tfbYraltoaG2nobWdxtb2I77spbdQwEdGLLhTQ4HugXehgI+g38QG3vkJ+g3hgI9wwE9mJEBm7DG5zEiQzJQAmZGuR+aO7eUk8bSczwa2Wmu3AxhjHgWuAjb2K/dvwHeBO4+pBiIiInE41lHyA+maVrahtSvU27u363t97gr4ruDvGnDX3NZBXUvP4LvW2GC8lrYO6lvbj/rI3LGIJ5wnALt7fS4H+szObow5Ayi21j5tjFE4i4iIJ/WeVrbgOFvy/XV2Whqi7dT1ejyursU9Hlfb3MZt343/XMc9IMwY4wN+ANwcR9nbgdsB8vPzKSsrO96vlzg0NDToWieJrnXy6Fonj6710IVxL3w71vlu4gnnPUDvJ76LYvu6ZABzgLLYKLmxwFPGmCv7Dwqz1t4P3A8wc+ZMW1paeozVlaEoKytD1zo5dK2TR9c6eXStky+e4WirgOnGmBJjTAi4Dniq66C1ttZaO8ZaO9laOxl4FTgsmEVERCQ+g4aztbYd+CzwDPA2sMxau8EY8y1jzJUnuoIiIiKjTVz3nK21y4Hl/fbddYSypcdfLRERkdFrBE+KKiIicnJSOIuIiHiMwllERMRjFM4iIiIeo3AWERHxGIWziIiIxyicRUREPEbhLCIi4jEKZxEREY9ROIuIiHiMwllERMRjFM4iIiIeo3AWERHxGIWziIiIxyicRUREPEbhLCIi4jEKZxEREY9ROIuIiHiMwllERMRjFM4iIiIeo3AWERHxGIWziIiIxyicRUREPEbhLCIi4jEKZxEREY9ROIuIiHiMwllERMRjFM4iIiIeo3AWERHxGIWziIiIxyicRUREPEbhLCIi4jEKZxEREY9ROIuIiHiMwllERMRjFM4iIiIeo3AWERHxGIWziIiIxyicRUREPEbhLCIi4jEKZxEREY9ROIuIiHiMwllERMRjFM4iIiIeo3AWERHxGIWziIiIx8QVzsaYy4wxm4wxW40xSwc4/kVjzEZjzFvGmOeNMZMSX1UREZHRYdBwNsb4gXuA9wKzgeuNMbP7FXsTOMtaOw94DPheoisqIiIyWsTTcj4b2Gqt3W6tjQKPAlf1LmCtXWGtbYp9fBUoSmw1RURERo9AHGUmALt7fS4HFh6l/CeBPw10wBhzO3A7QH5+PmVlZfHVUo5LQ0ODrnWS6Fonj6518uhaJ1884Rw3Y8yNwFnA+QMdt9beD9wPMHPmTFtaWprIr5cjKCsrQ9c6OXStk0fXOnl0rZMvnnDeAxT3+lwU29eHMeYi4KvA+dba1sRUT0REZPSJ557zKmC6MabEGBMCrgOe6l3AGHM6cB9wpbX2QOKrKSIiMnoMGs7W2nbgs8AzwNvAMmvtBmPMt4wxV8aK3Q2kA/9rjFljjHnqCKcTERGRQcR1z9lauxxY3m/fXb22L0pwvUREREYtzRAmIiLiMQpnERERj1E4i4iIeIzCWURExGMUziIiIh6jcBYREfEYhbOIiIjHKJxFREQ8RuEsIiLiMQpnERERj1E4i4iIeIzCWURExGMUziIiIh6jcBYREfEYhbOIiIjHKJxFREQ8RuEsIiLiMQpnERERj1E4i4iIeIzCWURExGMUziIiIh6jcBYREfEYhbOIiIjHKJxFREQ8RuEsIiLiMQpnERERj1E4i4iIeIzCWURExGMUziIiIh6jcBYREfEYhbOIiIjHKJxFREQ8RuEsIiLiMQpnERERj1E4i4iIeIzCWURExGMUziIiIh6jcBYREfEYhbOIiIjHKJxFREQ8RuEsIiLiMQpnERERj1E4i4iIeIzCWURExGMUziIiIh4TVzgbYy4zxmwyxmw1xiwd4HjYGPPb2PHXjDGTE11RERGR0WLQcDbG+IF7gPcCs4HrjTGz+xX7JFBtrZ0G/BD4bqIrKiIiMlrE03I+G9hqrd1urY0CjwJX9StzFfBQbPsx4EJjjElcNUVEREaPeMJ5ArC71+fy2L4By1hr24FaIC8RFRQRERltAsn8MmPM7cDtsY+txpj1yfz+UWwMcGi4KzFK6Fonj6518uhaJ8akeAvGE857gOJen4ti+wYqU26MCQBZQGX/E1lr7wfuBzDGvG6tPSveisrQ6Vonj6518uhaJ4+udfLF0629CphujCkxxoSA64Cn+pV5Crgptv0R4K/WWpu4aoqIiIweg7acrbXtxpjPAs8AfuBBa+0GY8y3gNettU8BPwd+bYzZClThAlxERESGIK57ztba5cDyfvvu6rXdAlx9jN99/zGWl6HTtU4eXevk0bVOHl3rJDPqfRYREfEWTd8pIiLiMcMSzoNNBypDZ4x50BhzoPdjasaYXGPMc8aYLbF1znDW8WRhjCk2xqwwxmw0xmwwxnw+tl/XO8GMMRFjzN+NMWtj1/qbsf0lsSmDt8amEA4Nd11PFsYYvzHmTWPMH2Ofda2TKOnhHOd0oDJ0vwQu67dvKfC8tXY68Hzssxy/duCfrbWzgUXAZ2L/Let6J14rcIG19jRgPnCZMWYRbqrgH8amDq7GTSUsifF54O1en3Wtk2g4Ws7xTAcqQ2StfRE3Yr633tOrPgR8IKmVOklZa/dZa1fHtutx/5BNQNc74azTEPsYjC0WuAA3ZTDoWieMMaYIuAJ4IPbZoGudVMMRzvFMByqJVWit3RfbrgAKh7MyJ6PYm9hOB15D1/uEiHWzrgEOAM8B24Ca2JTBoH9LEun/Af8KdMY+56FrnVQaEDbKxCaH0RD9BDLGpAOPA1+w1tb1PqbrnTjW2g5r7XzcLIVnA7OGuUonJWPM+4AD1to3hrsuo1lS59aOiWc6UEms/caYcdbafcaYcbiWhySAMSaIC+aHrbVPxHbrep9A1toaY8wKYDGQbYwJxFp0+rckMc4FrjTGXA5EgEzgR+haJ9VwtJzjmQ5UEqv39Ko3AU8OY11OGrH7cD8H3rbW/qDXIV3vBDPG5BtjsmPbKcDFuHv8K3BTBoOudUJYa79srS2y1k7G/fv8V2vtDehaJ9WwTEIS+4vs/9EzHeh/JL0SJyljzCNAKe4tMvuBrwO/B5YBE4GdwDXW2v6DxuQYGWPeA7wErKPn3txXcPeddb0TyBgzDzcIyY9rVCyz1n7LGDMFN6g0F3gTuNFa2zp8NT25GGNKgX+x1r5P1zq5NEOYiIiIx2hAmIiIiMconEVERDxG4SwiIuIxCmcRERGPUTiLiIh4jMJZRETEYxTOIiIiHqNwFhER8Zj/DwaZdq0NyUMCAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_learning_curves(history):\n",
    "    pd.DataFrame(history.history).plot(figsize=(8, 5))\n",
    "    plt.grid(True)\n",
    "    plt.gca().set_ylim(0, 1)\n",
    "    plt.show()\n",
    "plot_learning_curves(history)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5160/5160 [==============================] - 0s 33us/sample - loss: 0.4243\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.42432791586070095"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(x_test_scaled, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
